<?php
// +----------------------------------------------------------------------
// | 杭州十禾信息科技有限公司
// +----------------------------------------------------------------------
// | Copyright (c) 2013-2015 http://www.shelpe.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
// +----------------------------------------------------------------------
// | Author: LeePuman <ysyzlsm@163.com>
// +----------------------------------------------------------------------

/**
 * 自动开车服务. 根据用户选择的商品, 自动选择关键词及价格进行投放,
 * 并且根据效果自动增删改关键词.
 */
class KeywordtoolAction extends NewzanAction {
	
	/** @var ProductQueueModel */
    private $_autoProductQueueMdl = null;
    /** @var Model */
    private $_autoKeywordLogMdl= null;
    /** @var KeywordModel */ 
	private $_keywordMdl = null;
	/** @var ProductModel */
	private $_productMdl = null;
	/** @var AutoDriveBaseModel */
	private $_autoDriveMdl = null;
	
	function sortWords(&$words,$WordTbStats3Days,$WordCateStats3Days,$item) {
		$item=(array)$item;
		$tbStats = $WordTbStats3Days;
    	$cateStats = $WordCateStats3Days;
    	$catsim = array();
	    foreach($words as $word => $weight) {
				if($word)
	    			$catsim[$word] = $this->cateSim($cateStats[$word], $tbStats[$word]);
	    }
	    $keywordMdl=new KeywordModel();
		$prodSim = $keywordMdl->getWordSim($item['title'], array_keys($words));

    		// 目前的服务给出的属性词与标题的相似度较低，需要特殊处理：把属性词当作完全匹配。
    	foreach($words as $word => $weight) {
    		if(in_array($weight, array(71, 83, 85, 86))) {
    			$prodSim[$word] = zh_strlen($word) / zh_strlen($words['title']);
    		}
    	}
    	$Similarity = array();
	    foreach($words as $word => $weight) {
	    	$powProb=pow($prodSim[$word],1/2);
	    	$Similarity[$word] = pow($catsim[$word] *$powProb,1/2);
	    }
    	arsort($Similarity);
    	
    	// 将排序后的词再copy回$this->_cndWords并保持最初的权重.
    	$res = array();
    	foreach($Similarity as $word => $sortWeight) {
    		if($sortWeight>0.1){
    		$res[$word] = array(
    		'word'=>$word,
    		'weight'=>$words[$word],
    		'pv'=>$WordTbStats3Days[$word]['pv'],
    		'click'=>$WordTbStats3Days[$word]['click'],
    		'competition'=>$WordTbStats3Days[$word]['competition'],
    		'avg_price'=>$WordTbStats3Days[$word]['avg_price'],
    		);
    		}
    	}
    	$words = $res;
    	
    	return ;
    }
	function cateSim($cateStat, $tbStat) {
    	$catePv = isset($cateStat['pv']) ? $cateStat['pv'] + 1 : 1;
    	$tbPv = isset($tbStat['pv']) ? $tbStat['pv'] + 1 : 1;
    	$s = ($catePv / $tbPv) * (1 -  (  1.0 / sqrt($tbPv) )  );
    
    	$s=$s>1.0 ? 1.0 : $s;
    	//$s=$s<$this->_driveParams['lowCateSimThres'] ? 0.001 : $s;
    	return $s;
    }
    /**
     * 利用词的长度和词在淘宝的全网统计属性去重。
     */
    function rmDupWords(&$words,$WordTbStats3Days) {
    	$tbStats = $WordTbStats3Days;
    	$n = count($words);
    	// current word
    	$currWordOri = key($words);
    	$currWord = trim_all($currWordOri);
    	$currWordStat = $tbStats[$currWordOri];
    	$currWordLen = mb_strlen($currWord);
    	
    	$dupWrods = array();
    	
    	for($i = 1; $i < $n; ++$i) {
    		// next word
    		next($words);
    		$nextWordOri = key($words);
    		$nextWord = trim_all($nextWordOri);
    		$nextWordStat = $tbStats[$nextWordOri];
    		$nextWordLen = mb_strlen($nextWord);
    		
    		// comapre
    		if($currWordLen == $nextWordLen && $currWordStat['pv'] == $nextWordStat['pv'] 
    				&& $currWordStat['click'] == $nextWordStat['click']) {
    			//unset($this->_cndWords[$nextWordOri]); // DEBUG
    			$dupWrods[] = $nextWordOri;
    			
    			
    		} else {
    			$currWordOri = $nextWordOri;
    			$currWord = $nextWord;
    			$currWordStat = $nextWordStat;
    			$currWordLen = $nextWordLen;
    		}
    	}
    	reset($words);
    	
    	// 删除重复的词
    	foreach($dupWrods as $word) {
    		unset($words[$word]); 
    	}
    	
    	return;
    }
	
	function checkDataWordTbStats3Days($word) {
		$keywordMdl=new KeywordModel();
    		$WordTbStats3Days = $keywordMdl->getTbStats(array_keys($word),
    				"pv,avg_price,competition,click,ctr",
    				date('Y-m-d', time() - 7 * 86400), date('Y-m-d', time() - 86400), false);
    	return $WordTbStats3Days;
    }
	function checkDataWordCateStats3Days($word,$catid) {
		$WordMdl=new WordModel();
    	$WordCateStats3Days = $WordMdl->getWordCatsBasicAvgProps(
    				array_keys($word), $catid,
    				time() - 7 * 86400, time() - 86400);
    	return $WordCateStats3Days;
    }
    
	function generateSign($params)
	{
		ksort($params);
		$stringToBeSigned = TB_SKEY;
		foreach ($params as $k => $v)
		{
			if("@" != substr($v, 0, 1))
			{
				$stringToBeSigned .= "$k$v";
			}
		}
		unset($k, $v);
		$stringToBeSigned .= TB_SKEY;

		return strtoupper(md5($stringToBeSigned));
	}
	function guessSex($word, $props = null) {
    	if($props) {
    		$propsArr = explode(',', $props);
    		foreach($propsArr as $prop) {
    			if($prop == '男') {
    				return 1;
    			} else if($prop == '女') {
    				return 0;
    			}
    		} 
    	}
    	$male = strpos($word, '男') !== false;
    	$female = strpos($word, '女') !== false;
    	return $male ? ($female ? -1 : 1) : ($female ? 0 : -1);
    }
	function guessSeason($word, $props = null) {
    	$codes = array('春' => 1, '夏' => 2, '秋' => 4, '冬' => 8);
    	$code = 0;
    	// 先检查标题
    	preg_match_all('/\x{6625}|\x{590f}|\x{79cb}|\x{51ac}/u', $word, $matches);
    	if($matches) {
    		foreach ($matches[0] as $match) {
    			$code = $code | $codes[$match];
    		}
    	}
    	// 标题未检出，检查属性
    	if($props && !$code) {
    		preg_match_all('/\x{6625}|\x{590f}|\x{79cb}|\x{51ac}/u', $props, $matches);
    		if($matches) {
    			foreach ($matches[0] as $match) {
    				$code = $code | $codes[$match];
    			}
    		}
    	}
    	return $code;
    }
	
	function filterWords(&$words,$item){
		if(!$words)
    		return ;
    	$item=(array)$item;
    	$titleOppoSex = 1 - $this->guessSex($item['title'], $item['product_props']);
    	$titleSeason = $this->guessSeason($item['title'], $item['product_props']);
    	foreach($words as $word => $weight){
    		//$this->filterShortWords();
    		if(zh_strlen($word)<= 2) 
    			unset($words[$word]);
    		//$this->filterBySex();
    		if($titleOppoSex != 2){ // 1 - (-1) = 2
    			if(($this->guessSex($word))== $titleOppoSex) {
    				unset($words[$word]);
    			}
    		}
    		//$this->filterBySeason();
    		if($titleSeason) {
    			$wordSeason = $this->guessSeason($word);
    			if($wordSeason && (($wordSeason & $titleSeason) == 0)) { //如果词也有季节，且不包含标题的季节，删除之。
    				unset($words[$word]);
    			}
    		}
    	}
	}
	
	function getwords($item){
		$item=(array) $item;
	    $category =  D('Category')->getCateName($item['cid']);
	    $productMdl=new ProductModel();
	    $props = $productMdl->getProductProps($item);
		$props = zh_strtolower(join(',', array_values($props))); // reset the keys
		$productType = zh_strtolower($productMdl->guessProductType($item['title'], $category));
		$item['product_type'] = $productType ? $productType : 'NULL';
		$item['product_props'] = $props;
	    $allRelatedWords = array();
	        
	    // 产品标题分词: weight = 61 ~ 66
	    $titleWords = $productMdl->getTitleWords($item, 60);
	    $allRelatedWords = array_merge($allRelatedWords, $titleWords);
	    
	    // 属性关键词 : weight = 81 ~ 86
	    $propWords = $productMdl->getPropTypeWords($item, 80);
	    $allRelatedWords = array_merge($allRelatedWords, $propWords);
	    
	    //  将类目热门词加入 52 
	    $conditons['id'] = $item['cid'];
    	$words = D('Category')->field('words')->where($conditons)->find();
    	$words = explode(',' , $words['words']);
    	foreach($words as $word) {
	    	$allRelatedWords[$word] = 52;
	    }
	    
	    	// 相关词: weight = 41
	    $wordMdl = new WordModel();
	    $relatedWords = $titleWords ? $wordMdl->getRelatedWords($titleWords, true , true) : array();
	    foreach($relatedWords as $word) {
	    	$allRelatedWords[$word] = 41;
	    }
	    //数据库相关词 61
	  /*  $keywordMdl=new KeywordModel();
	    $page=1;$pagesize=1000;
	    $count=$pagesize;
	    while($count==$pagesize){
	    	$ps=($page-1)*$pagesize;
	    	$dbwords=M('ztc_words.words')->limit("$ps,$pagesize")->select(array('field'=>'word'));
	    	$count=count($dbwords);
	    	foreach($dbwords as $key=>$word){
	    		if(trim($word['word'])){
	    			$dbwords[$key]=$word['word'];
	    		}else{
	    			unset($dbwords[$key]);
	    		}
	    	}
	    	$prodSims = $keywordMdl->getWordSim($item['title'], $dbwords);
	    	foreach($prodSims as $word=>$prodSim){
	    		if($prodSim>0.1){
	    			$allRelatedWords[$word]=61;
	    		}
	    	}
	    	$page++;
	    }*/
	    	
	    // 当猜出了产品时，词库搜索相关词 ， 最多200个 
	    	
	    if( !empty($item['product_type']) ){
	    		$weight=41;
	    		$filter = array(
    				array( 'field' => 'avg_price' , "min" => 0 , "max" => 999 ),
    				array( 'field' => 'pv' , "min" => 0 , "max" => 10000000),
    				array( 'field' => 'click' , "min" => 0 , "max" => 100000),
    				array( 'field' => 'ctr' , "min" => 0 , "max" => 10000 ),
    				array( 'field' => 'competition' , "min" => 0 , "max" => 10000)
    			);
    
    			$service_params = array(
    				'mykeywords' => $item['product_type'],
    				'cate_id' => $item['cid'],
    				'is_not' => 1,
    				'page' => 1,
    				'pagesize' => 200,
    				'filters' => json_encode($filter),
    				'order' => 'pv',
    				'asc' => 'false',
    				'timespan' => 'WEEK',
    			);
    			try{
    				import("@.Library.Carine");
    				$carine = new Carine();
    				$res = $carine->getFilterWords($service_params);
    				$result = json_decode($res, true);
    			}catch(Exception $e){
    			
    			}
    			$recommend_words = $result["response"]["keywords"];
    			$words = array();
    			foreach($recommend_words as $k => $w){
    				$word = $w['word'] ? $w['word'] : $k;
    				$words[ $word ] = $weight;
    			}
	    		$allRelatedWords = array_merge($allRelatedWords, $words);
	    }
	    	
	    return $allRelatedWords;
	}
}